<template>
	<div ref="container" class="preview-3d"></div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import EasyStar from "easystarjs"; // 引入EasyStarJS
export default {
	props: {
		features: { type: Array, required: true },
		height: { type: Number, default: 8 },
	},
	data() {
		return {
			scene: null,
			camera: null,
			renderer: null,
			controls: null,
			rooms: [],
			roads: [],
			startPoint: null,
			endPoint: null,
			pathfinder: null, // 路径规划器
			grid: null, // 路径规划网格
			gridWidth: 100, // 网格宽度
			gridHeight: 100, // 网格高度
			cellSize: 10, // 单元格大小
			gridColor: 0xcccccc, // 网格颜色
			gridOpacity: 0.5, // 网格透明度
			path: null, // 规划的路径
			pathMesh: null, // 路径网格对象
			gridHelper: null, // 网格辅助对象
			gridVisible: true, // 网格可见性
			gridSize: 50, // 网格线间距，默认50（原100）
			gridLineCount: 20, // 单侧最大线条数，防止网格过密
			floorBox: null, // 地板边界框
		};
	},
	mounted() {
		this.init3D();
		this.createPathfinder(); // 初始化路径规划器
		this.createBuildings();
		this.createGridHelper(); // 添加网格创建
		this.animate();
		this.$refs.container.addEventListener("click", this.onMouseClick);
	},
	methods: {
		// 创建网格辅助对象
		createGridHelper() {
			if (!this.gridWidth || !this.gridHeight) return;

			// 基于动态网格参数创建可视化网格
			const halfWidth = (this.gridWidth * this.cellSize) / 2;
			const halfHeight = (this.gridHeight * this.cellSize) / 2;

			// 创建网格点（原有逻辑不变）
			const points = [];

			// X轴方向线条（横向）
			for (let y = 0; y <= this.gridHeight; y++) {
				const z = y * this.cellSize - halfHeight;
				points.push(new THREE.Vector3(-halfWidth, 0, z));
				points.push(new THREE.Vector3(halfWidth, 0, z));
			}

			// Z轴方向线条（纵向）
			for (let x = 0; x <= this.gridWidth; x++) {
				const xPos = x * this.cellSize - halfWidth;
				points.push(new THREE.Vector3(xPos, 0, -halfHeight));
				points.push(new THREE.Vector3(xPos, 0, halfHeight));
			}

			// 创建几何体和材质
			const geometry = new THREE.BufferGeometry().setFromPoints(points);
			const material = new THREE.LineBasicMaterial({
				color: this.gridColor,
				linewidth: 1,
				transparent: true,
				opacity: this.gridOpacity,
				depthTest: true,
				depthWrite: false,
			});

			// 清理旧网格并添加新网格
			if (this.gridHelper) {
				this.scene.remove(this.gridHelper);
			}
			this.gridHelper = new THREE.LineSegments(geometry, material);
			this.scene.add(this.gridHelper);

			// 添加原点标记（可选）
			this.addGridOriginMarker();

			console.log(
				`网格已更新：单元格大小 ${this.cellSize}，总尺寸 ${this.gridWidth}×${this.gridHeight}`
			);
		},
		// 添加网格原点标记
		addGridOriginMarker() {
			// 清理旧标记
			const oldMarker = this.scene.getObjectByName("gridOriginMarker");
			if (oldMarker) this.scene.remove(oldMarker);

			// 创建新标记
			const markerGeometry = new THREE.SphereGeometry(5, 16, 16);
			const markerMaterial = new THREE.MeshBasicMaterial({
				color: 0xff0000,
			});
			const marker = new THREE.Mesh(markerGeometry, markerMaterial);
			marker.position.set(0, 0.1, 0); // 略高于地面
			marker.name = "gridOriginMarker";
			this.scene.add(marker);
		},
		// 修改坐标转换方法，使原点居中并支持动态偏移
		worldToGrid(worldPos) {
			const halfWidth = (this.gridWidth * this.cellSize) / 2;
			const halfHeight = (this.gridHeight * this.cellSize) / 2;

			// 计算相对于网格中心的偏移
			const gridX = Math.floor((worldPos.x + halfWidth) / this.cellSize);
			const gridY = Math.floor((worldPos.z + halfHeight) / this.cellSize);

			// 确保坐标在网格范围内
			return {
				x: Math.max(0, Math.min(this.gridWidth - 1, gridX)),
				y: Math.max(0, Math.min(this.gridHeight - 1, gridY)),
			};
		},

		gridToWorld(gridPos) {
			const halfWidth = (this.gridWidth * this.cellSize) / 2;
			const halfHeight = (this.gridHeight * this.cellSize) / 2;

			// 从网格坐标转换为世界坐标，以中心为原点
			const worldX =
				gridPos.x * this.cellSize - halfWidth + this.cellSize / 2;
			const worldZ =
				gridPos.y * this.cellSize - halfHeight + this.cellSize / 2;

			return new THREE.Vector3(worldX, 0, worldZ);
		},

		// 新增：设置网格大小的方法
		setGridSize(size) {
			this.gridSize = Math.max(10, size); // 最小10单位
			this.createGridHelper(); // 重新创建网格
		},

		// 切换网格可见性
		toggleGridVisibility() {
			this.gridVisible = !this.gridVisible;
			if (this.gridHelper) {
				this.gridHelper.visible = this.gridVisible;
			}
		},
		init3D() {
			this.scene = new THREE.Scene();
			this.scene.background = new THREE.Color(0xffffff);

			this.camera = new THREE.PerspectiveCamera(
				75,
				this.$refs.container.clientWidth /
					this.$refs.container.clientHeight,
				0.1,
				1000
			);
			this.camera.position.set(0, 100, 150);

			this.renderer = new THREE.WebGLRenderer({ antialias: true });
			this.renderer.setSize(
				this.$refs.container.clientWidth,
				this.$refs.container.clientHeight
			);
			this.$refs.container.appendChild(this.renderer.domElement);

			this.controls = new OrbitControls(
				this.camera,
				this.renderer.domElement
			);
			this.controls.mouseButtons = {
				LEFT: this.controls.mouseButtons.RIGHT,
				RIGHT: this.controls.mouseButtons.LEFT,
			};
			this.controls.screenSpacePanning = false;
			this.controls.enableDamping = true;
			this.controls.minPolarAngle = 0;
			this.controls.maxPolarAngle = Math.PI / 2;

			this.scene.add(new THREE.AmbientLight(0xffffff, 0.5));

			const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
			directionalLight.position.set(10, 10, 10);
			this.scene.add(directionalLight);
		},

		// 初始化路径规划器
		createPathfinder() {
			this.pathfinder = new EasyStar.js();
			this.pathfinder.setGrid(this.createEmptyGrid());
			this.pathfinder.setAcceptableTiles([0]); // 可通行的格子

			// 启用对角线移动以模拟欧几里得距离
			this.pathfinder.enableDiagonals();

			// 设置对角线移动的代价为√2，近似欧几里得距离
			this.pathfinder.setTileCost(0, 1); // 水平/垂直移动代价
			this.pathfinder.setTileCost(1, 0); // 障碍物代价
			// this.pathfinder.setTileCost(2, Math.SQRT2); // 对角线移动代价

			// 设置只允许八个方向移动（上下左右+对角线）
			if (typeof this.pathfinder.setDirectionalCondition === "function") {
				this.pathfinder.setDirectionalCondition(
					0,
					0,
					true, // 上
					true, // 右
					true, // 下
					true, // 左
					false, // 右上
					false, // 右下
					false, // 左下
					false // 左上
				);
			}

			// 启用对角线移动时允许切角
			// this.pathfinder.enableCornerCutting();

			// 优化搜索参数以提高性能
			this.pathfinder.setIterationsPerCalculation(1000); // 增加每次计算的迭代次数
		},

		// 创建空网格
		createEmptyGrid() {
			this.grid = [];
			for (let y = 0; y < this.gridHeight; y++) {
				this.grid[y] = [];
				for (let x = 0; x < this.gridWidth; x++) {
					this.grid[y][x] = 0; // 0表示可通行，1表示障碍
				}
			}
			return this.grid;
		},

		// 根据房间更新网格障碍
		updateGridWithRooms() {
			// 重置网格
			this.grid = this.createEmptyGrid();

			// 将房间位置标记为障碍
			this.rooms.forEach((room) => {
				const box = new THREE.Box3().setFromObject(room);

				// 减少边界余量，仅使用0.5个单元格
				const margin = 0;
				const minGrid = this.worldToGrid(
					new THREE.Vector3(
						box.min.x - margin * this.cellSize,
						0,
						box.min.z - margin * this.cellSize
					)
				);

				const maxGrid = this.worldToGrid(
					new THREE.Vector3(
						box.max.x + margin * this.cellSize,
						0,
						box.max.z + margin * this.cellSize
					)
				);

				// 确保网格坐标在有效范围内
				const clampedMinX = Math.max(0, minGrid.x);
				const clampedMaxX = Math.min(this.gridWidth - 1, maxGrid.x);
				const clampedMinY = Math.max(0, minGrid.y);
				const clampedMaxY = Math.min(this.gridHeight - 1, maxGrid.y);

				// 标记为障碍
				for (let y = clampedMinY; y <= clampedMaxY; y++) {
					for (let x = clampedMinX; x <= clampedMaxX; x++) {
						this.grid[y][x] = 1;
					}
				}
			});

			// 更新路径规划器中的网格
			this.pathfinder.setGrid(this.grid);

			// 可视化调试（可选）
			this.visualizeGridDebug();
		},
		// 增强可视化调试
		visualizeGridDebug() {
			// 清理旧的调试可视化
			const oldDebugMeshes = this.scene.children.filter(
				(child) => child.name && child.name.startsWith("gridDebug_")
			);
			oldDebugMeshes.forEach((mesh) => this.scene.remove(mesh));

			// 创建新的调试可视化
			for (let y = 0; y < this.gridHeight; y++) {
				for (let x = 0; x < this.gridWidth; x++) {
					if (this.grid[y][x] === 1) {
						// 障碍物单元格
						const worldPos = this.gridToWorld({ x, y });

						const geometry = new THREE.BoxGeometry(
							this.cellSize * 0.9, // 稍微缩小以显示网格线
							0.2, // 高度
							this.cellSize * 0.9
						);

						const material = new THREE.MeshBasicMaterial({
							color: 0xff0000,
							transparent: true,
							opacity: 0.3,
						});

						const cube = new THREE.Mesh(geometry, material);
						cube.position.set(worldPos.x, 0.1, worldPos.z);
						cube.name = `gridDebug_${x}_${y}`;
						this.scene.add(cube);
					} else {
						// 可通行单元格（半透明绿色）
						const worldPos = this.gridToWorld({ x, y });

						const geometry = new THREE.BoxGeometry(
							this.cellSize * 0.1, // 小标记
							0.1,
							this.cellSize * 0.1
						);

						const material = new THREE.MeshBasicMaterial({
							color: 0x00ff00,
							transparent: true,
							opacity: 0.2,
						});

						const cube = new THREE.Mesh(geometry, material);
						cube.position.set(worldPos.x, 0.05, worldPos.z);
						cube.name = `gridDebug_${x}_${y}`;
						this.scene.add(cube);
					}
				}
			}
		},
		// 执行路径规划
		//修改路径规划方法，使用改进的寻找可行点逻辑
		planPath() {
			if (!this.startPoint || !this.endPoint) return;

			// 确保网格是最新的
			this.updateGridWithRooms();

			// 获取起点和终点的中心点
			const startCenter = this.getRoomCenter(this.startPoint);
			const endCenter = this.getRoomCenter(this.endPoint);

			// 转换为网格坐标
			const startGrid = this.worldToGrid(startCenter);
			const endGrid = this.worldToGrid(endCenter);

			// 尝试在起点终点周围找到可行点，使用改进的搜索算法
			const adjustedStart = this.findWalkablePosition(startGrid);
			const adjustedEnd = this.findWalkablePosition(endGrid);

			if (!adjustedStart || !adjustedEnd) {
				console.warn("无法在起点或终点附近找到可行路径点");
				return;
			}

			// 清除之前的路径
			if (this.pathMesh) {
				this.scene.remove(this.pathMesh);
				this.pathMesh = null;
			}

			// 规划路径
			this.pathfinder.findPath(
				adjustedStart.x,
				adjustedStart.y,
				adjustedEnd.x,
				adjustedEnd.y,
				(path) => {
					this.handlePathResult(path, startCenter, endCenter);
				}
			);

			this.pathfinder.calculate();
		},

		// 改进寻找可行点的算法，优先在点击位置附近搜索
		findWalkablePosition(gridPos, maxSearchDistance = 5) {
			// 先检查点击位置本身是否可行
			if (this.isWalkable(gridPos.x, gridPos.y)) {
				return gridPos;
			}

			// 按距离排序的搜索方向（八个方向）
			const directions = [
				{ x: 0, y: 1 },
				{ x: 1, y: 1 },
				{ x: 1, y: 0 },
				{ x: 1, y: -1 },
				{ x: 0, y: -1 },
				{ x: -1, y: -1 },
				{ x: -1, y: 0 },
				{ x: -1, y: 1 },
			];

			// 分层搜索，从近到远
			for (let distance = 1; distance <= maxSearchDistance; distance++) {
				// 对每个方向，按距离递增搜索
				for (const dir of directions) {
					for (let d = 1; d <= distance; d++) {
						const checkX = gridPos.x + dir.x * d;
						const checkY = gridPos.y + dir.y * d;

						// 确保在网格范围内
						if (
							checkX >= 0 &&
							checkX < this.gridWidth &&
							checkY >= 0 &&
							checkY < this.gridHeight
						) {
							if (this.isWalkable(checkX, checkY)) {
								return { x: checkX, y: checkY };
							}
						}
					}
				}
			}

			return null; // 找不到可行点
		},

		// 检查指定网格位置是否可行走
		isWalkable(x, y) {
			return this.grid[y][x] === 0;
		},
		// 处理路径规划结果
		handlePathResult(path, startCenter, endCenter) {
			if (!path || path.length === 0) {
				console.warn("无法找到路径");
				return;
			}

			this.path = path;

			// 创建路径点 - 从起点的网格位置开始，而不是精确的起点
			const startGrid = this.worldToGrid(startCenter);
			const startWorldPos = this.gridToWorld(startGrid);
			const pathPoints = [startWorldPos];

			// 添加所有中间网格点
			path.forEach((point) => {
				const worldPos = this.gridToWorld(point);
				worldPos.y = startCenter.y; // 保持高度一致
				pathPoints.push(worldPos);
			});

			// 添加终点的网格位置，而不是精确的终点
			const endGrid = this.worldToGrid(endCenter);
			const endWorldPos = this.gridToWorld(endGrid);
			pathPoints.push(endWorldPos);

			// 创建路径几何体
			const pathGeometry = new THREE.BufferGeometry().setFromPoints(
				pathPoints
			);

			// 创建路径材质
			const pathMaterial = new THREE.LineBasicMaterial({
				color: 0xff00ff,
				linewidth: 5,
				transparent: true,
				opacity: 0.8,
			});

			// 创建路径对象
			if (this.pathMesh) {
				this.scene.remove(this.pathMesh);
			}
			this.pathMesh = new THREE.Line(pathGeometry, pathMaterial);
			this.scene.add(this.pathMesh);
			console.log("路径点列表:");
			pathPoints.forEach((point, index) => {
				console.log(
					`点 ${index}: (${point.x.toFixed(2)}, ${point.z.toFixed(
						2
					)})`
				);
			});
			console.log("路径规划完成，路径点数量:", pathPoints.length);
		},
		createBuildings() {
			// 原有代码...
			let allCoordinates = [];
			this.features.forEach((feature) => {
				if (
					feature.layerType !== "path" &&
					feature.coordinates &&
					feature.coordinates[0] &&
					Array.isArray(feature.coordinates[0])
				) {
					allCoordinates = allCoordinates.concat(
						this.filterValidCoordinates(feature.coordinates[0])
					);
				}
			});

			let centerX = 112.45,
				centerY = 37.75;
			if (allCoordinates.length > 0) {
				const xs = allCoordinates
					.map((coord) => coord[0])
					.filter((x) => !isNaN(x));
				const ys = allCoordinates
					.map((coord) => coord[1])
					.filter((y) => !isNaN(y));

				if (xs.length > 0 && ys.length > 0) {
					centerX = (Math.min(...xs) + Math.max(...xs)) / 2;
					centerY = (Math.min(...ys) + Math.max(...ys)) / 2;
				}
			}

			this.features.forEach((feature) => {
				if (!feature.coordinates || !feature.coordinates[0]) {
					console.warn("特征缺少坐标数据:", feature);
					return;
				}

				if (feature.layerType === "floor") {
					this.createFloor(
						feature.coordinates[0],
						centerX,
						centerY,
						this.height
					);
				} else if (feature.layerType === "room") {
					this.createRoom(
						feature.coordinates[0],
						centerX,
						centerY,
						this.height
					);
				} else if (feature.layerType === "road") {
					this.createRoad(
						feature.coordinates[0],
						centerX,
						centerY,
						this.height
					);
				}
			});
			// 确保所有房间创建后更新网格障碍
			this.$nextTick(() => {
				this.updateGridWithRooms();
			});
		},

		createRoom(coordinates, centerX, centerY, height) {
			// 过滤无效坐标点
			coordinates = this.filterValidCoordinates(coordinates);
			if (coordinates.length < 3) {
				console.warn("房间坐标点不足，至少需要3个点:", coordinates);
				return;
			}

			// 创建点集合
			const points = coordinates.map((coord) => {
				return new THREE.Vector2(
					(coord[0] - centerX) * 1000,
					(coord[1] - centerY) * 1000
				);
			});

			// 验证并修复自相交的形状
			if (!this.isValidShape(points)) {
				console.warn("房间形状无效，尝试修复...");
				points = this.fixShape(points);

				if (points.length < 3) {
					console.error("无法修复房间形状，跳过创建");
					return;
				}
			}

			// 创建房间形状
			const shape = new THREE.Shape(points);
			const roomHeight = height;

			// 创建几何体
			const geometry = new THREE.ExtrudeGeometry(shape, {
				depth: roomHeight,
				bevelEnabled: true,
				curveSegments: 1,
				steps: 1,
			});

			// 验证几何体
			if (!this.validateGeometry(geometry)) {
				console.error("房间几何体无效，跳过创建");
				return;
			}

			// 创建材质和网格
			const material = new THREE.MeshLambertMaterial({
				color: 0x87ceeb,
				side: THREE.DoubleSide,
				transparent: false,
				opacity: 0.5,
			});

			const room = new THREE.Mesh(geometry, material);
			room.rotation.x = -Math.PI / 2;
			room.position.y = -height + 1;
			room.userData = {
				originalColor: 0x87ceeb,
				type: "room",
				center: this.getRoomCenter(room),
			};

			this.rooms.push(room);
			this.scene.add(room);

			// 添加顶面边缘蓝色周长线
			const linePoints = points.map(
				(p) => new THREE.Vector3(p.x, p.y, roomHeight)
			);
			if (
				points.length > 0 &&
				!points[0].equals(points[points.length - 1])
			) {
				linePoints.push(
					new THREE.Vector3(points[0].x, points[0].y, roomHeight)
				);
			}

			if (linePoints.length >= 2) {
				const lineGeometry = new THREE.BufferGeometry().setFromPoints(
					linePoints
				);
				const lineMaterial = new THREE.LineBasicMaterial({
					color: 0x0000ff,
					linewidth: 5,
					transparent: false,
					depthTest: true,
					depthWrite: true,
				});

				const perimeterLine = new THREE.Line(
					lineGeometry,
					lineMaterial
				);
				perimeterLine.rotation.x = -Math.PI / 2;
				perimeterLine.position.y = -height + 1.2;
				perimeterLine.updateMatrix();
				this.scene.add(perimeterLine);
			} else {
				console.warn(
					"无法创建房间周长线，点数量不足:",
					linePoints.length
				);
			}
		},
		createRoad(coordinates, centerX, centerY, height) {
			// 过滤无效坐标点
			coordinates = this.filterValidCoordinates(coordinates);
			if (coordinates.length < 3) {
				console.warn("道路坐标点不足，至少需要3个点:", coordinates);
				return;
			}

			// 创建点集合
			const points = coordinates.map((coord) => {
				return new THREE.Vector2(
					(coord[0] - centerX) * 1000,
					(coord[1] - centerY) * 1000
				);
			});

			// 验证并修复自相交的形状
			if (!this.isValidShape(points)) {
				console.warn("道路形状无效，尝试修复...");
				points = this.fixShape(points);

				if (points.length < 3) {
					console.error("无法修复道路形状，跳过创建");
					return;
				}
			}

			// 创建道路形状
			const shape = new THREE.Shape(points);
			const geometry = new THREE.ShapeGeometry(shape);

			// 验证几何体
			if (!this.validateGeometry(geometry)) {
				console.error("道路几何体无效，跳过创建");
				return;
			}

			// 创建材质和网格
			const material = new THREE.MeshBasicMaterial({
				color: 0x999999,
				transparent: true,
				opacity: 0.8,
			});

			const road = new THREE.Mesh(geometry, material);
			road.rotation.x = -Math.PI / 2;
			road.position.y = 0.1;
			road.userData = {
				type: "road",
				shape: shape,
				points: points,
			};

			this.roads.push(road);
			this.scene.add(road);
		},
		createFloor(coordinates, centerX, centerY, height) {
			// 过滤无效坐标点
			coordinates = this.filterValidCoordinates(coordinates);
			if (coordinates.length < 3) {
				console.warn("楼板坐标点不足，至少需要3个点:", coordinates);
				return;
			}

			// 创建点集合
			const points = coordinates.map((coord) => {
				return new THREE.Vector2(
					(coord[0] - centerX) * 1000,
					(coord[1] - centerY) * 1000
				);
			});

			// 验证并修复自相交的形状
			if (!this.isValidShape(points)) {
				console.warn("楼板形状无效，尝试修复...");
				points = this.fixShape(points);

				if (points.length < 3) {
					console.error("无法修复楼板形状，跳过创建");
					return;
				}
			}

			const shape = new THREE.Shape(points);
			const slabThickness = 1;
			const geometry = new THREE.ExtrudeGeometry(shape, {
				depth: slabThickness,
				bevelEnabled: true,
				curveSegments: 1,
				steps: 1,
			});

			// 验证几何体
			if (!this.validateGeometry(geometry)) {
				console.error("楼板几何体无效，跳过创建");
				return;
			}

			// 创建材质和网格
			const material = new THREE.MeshLambertMaterial({
				color: 0xf5f5f5,
				side: THREE.DoubleSide,
				transparent: false,
				opacity: 1.0,
			});

			const floorSlab = new THREE.Mesh(geometry, material);
			floorSlab.rotation.x = -Math.PI / 2;
			floorSlab.position.y = -height + slabThickness / 2;
			this.scene.add(floorSlab);
			const floorBox = new THREE.Box3().setFromObject(floorSlab);
			this.floorBox = floorBox;
			this.updateGridBasedOnFloor(); // 根据地板更新网格
		},
		updateGridBasedOnFloor() {
			if (!this.floorBox) return;

			// 计算地板实际尺寸（X和Z轴范围）
			const floorWidth = this.floorBox.max.x - this.floorBox.min.x;
			const floorDepth = this.floorBox.max.z - this.floorBox.min.z;

			// 减少边缘留白，使网格更贴合地板
			const padding = 2; // 减小留白为2个单元格

			// 计算合适的网格行列数
			this.cellSize = 5; // 基础单元格大小
			this.gridWidth = Math.ceil(
				(floorWidth + padding * this.cellSize) / this.cellSize
			);
			this.gridHeight = Math.ceil(
				(floorDepth + padding * this.cellSize) / this.cellSize
			);

			// 重新创建网格
			this.createGridHelper();
		},
		getRoomCenter(room) {
			if (!room) return new THREE.Vector3();

			const box = new THREE.Box3().setFromObject(room);
			const center = new THREE.Vector3();
			box.getCenter(center);

			// 确保中心高度与路径一致
			center.y = 0.1; // 与路径高度保持一致

			return center;
		},

		// 过滤无效坐标点
		filterValidCoordinates(coordinates) {
			if (!Array.isArray(coordinates)) {
				console.warn("坐标数据不是数组:", coordinates);
				return [];
			}

			return coordinates.filter((coord) => {
				if (!Array.isArray(coord) || coord.length < 2) {
					console.warn("无效坐标点:", coord);
					return false;
				}

				// 检查坐标是否为有效数字
				if (isNaN(coord[0]) || isNaN(coord[1])) {
					console.warn("坐标包含NaN值:", coord);
					return false;
				}

				// 检查坐标是否为无穷大
				if (!isFinite(coord[0]) || !isFinite(coord[1])) {
					console.warn("坐标包含无穷大值:", coord);
					return false;
				}

				return true;
			});
		},
		// 验证形状有效性
		isValidShape(points) {
			return true;
			if (!Array.isArray(points) || points.length < 3) {
				return false;
			}

			// 检查是否有重复点
			for (let i = 0; i < points.length; i++) {
				for (let j = i + 1; j < points.length; j++) {
					if (points[i].equals(points[j])) {
						return false;
					}
				}
			}

			return true;
		},
		// 修复无效形状
		fixShape(points) {
			if (!Array.isArray(points)) return [];

			// 移除重复点
			const uniquePoints = [];
			points.forEach((point) => {
				if (!uniquePoints.some((p) => p.equals(point))) {
					uniquePoints.push(point);
				}
			});

			return uniquePoints;
		},
		// 验证几何体有效性
		validateGeometry(geometry) {
			if (
				!geometry ||
				!geometry.attributes ||
				!geometry.attributes.position
			) {
				return false;
			}

			const position = geometry.attributes.position;

			// 检查顶点数量
			if (position.count < 3) {
				console.warn("几何体顶点数量不足:", position.count);
				return false;
			}

			// 检查是否有NaN或无穷大值
			for (let i = 0; i < position.count; i++) {
				if (
					isNaN(position.getX(i)) ||
					isNaN(position.getY(i)) ||
					isNaN(position.getZ(i)) ||
					!isFinite(position.getX(i)) ||
					!isFinite(position.getY(i)) ||
					!isFinite(position.getZ(i))
				) {
					console.warn("几何体包含无效顶点数据，索引:", i);
					return false;
				}
			}

			return true;
		},

		onMouseClick(event) {
			if (!this.$refs.container) return;

			const rect = this.$refs.container.getBoundingClientRect();
			const mouse = new THREE.Vector2();
			mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
			mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

			const raycaster = new THREE.Raycaster();
			raycaster.setFromCamera(mouse, this.camera);

			if (!this.rooms || this.rooms.length === 0) return;

			const intersects = raycaster.intersectObjects(this.rooms);

			if (intersects.length > 0 && intersects[0].object) {
				const clickedRoom = intersects[0].object;

				// 重置所有房间颜色
				this.rooms.forEach((room) => {
					if (room && room.material && room.userData) {
						room.material.color.set(room.userData.originalColor);
					}
				});

				// 点击逻辑：设置起点和终点
				if (!this.startPoint) {
					this.startPoint = clickedRoom;
					if (this.startPoint && this.startPoint.material) {
						this.startPoint.material.color.set(0x00ff00);
					}
					this.endPoint = null;
				} else if (!this.endPoint && clickedRoom !== this.startPoint) {
					this.endPoint = clickedRoom;
					if (this.endPoint && this.endPoint.material) {
						this.endPoint.material.color.set(0xff0000);
					}

					// 当起点和终点都存在时进行路径规划
					if (this.startPoint && this.endPoint) {
						this.planPath(); // 执行路径规划
					}
				} else {
					// 重置并设置新起点
					this.startPoint = clickedRoom;
					if (this.startPoint && this.startPoint.material) {
						this.startPoint.material.color.set(0x00ff00);
					}
					this.endPoint = null;
				}
			}
		},

		animate() {
			requestAnimationFrame(this.animate.bind(this));
			if (this.controls) this.controls.update();
			if (this.renderer && this.scene && this.camera) {
				this.renderer.render(this.scene, this.camera);
			}
		},
	},
	beforeUnmount() {
		if (this.$refs.container) {
			this.$refs.container.removeEventListener(
				"click",
				this.onMouseClick
			);
		}

		if (this.renderer) {
			this.renderer.dispose();
			if (this.$refs.container) {
				this.$refs.container.removeChild(this.renderer.domElement);
			}
		}

		if (this.controls) this.controls.dispose();

		// 清理路径规划器
		if (this.pathfinder) {
			this.pathfinder = null;
		}
	},
	watch: {
		features: {
			deep: true,
			handler() {
				if (!this.scene) return;

				this.scene.traverse((child) => {
					if (
						child instanceof THREE.Mesh &&
						child !== this.controls?.object &&
						!child.isCube
					) {
						this.scene.remove(child);
					}
				});

				this.rooms = [];
				this.roads = [];
				this.path = null;

				if (this.pathMesh) {
					this.scene.remove(this.pathMesh);
					this.pathMesh = null;
				}

				this.createBuildings();
			},
		},
	},
};
</script>

<style scoped>
.preview-3d {
	width: 100%;
	height: 100%;
}
</style>
